#!/bin/bash

# ports to be checked, seperated by comma.
PORTS="{{PORTS}}"
# supported protocols, available values: all, tcp, udp.
PROTOCOL="{{PROTOCOL}}"

gen_result() {
  result=$1
  err_info=$2
  if [ "$result" == "success" ]; then
    echo "result: success"
  else
    echo "result: failed"
    echo "reason: $err_info"
  fi
  exit 0;
}

check_param() {
  protocol=$1
  if [ "$protocol" != "all" ] && [ "$protocol" != "tcp" ] && [ "$protocol" != "udp" ]; then
    gen_result "failed" "PROTOCOL $protocol is not valid."
  fi

  ports=$2
  IFS=',' read -ra arr <<< "$ports"
  for port in "${arr[@]}"; do
    [ -n "${port##*[!0-9]*}" ] || gen_result "failed" "port is not number."
  done
}

open_port() {
  port=$1
  protocol=$2
  protocols=($protocol)
  if [ "$protocol" == "all" ]; then
    protocols=("tcp" "udp")
  fi

  for item in "${protocols[@]}"; do
    # clear outdated `DROP` and `ACCEPT` rules if exists.
    iptables -D INPUT -p "$item" --dport "$port" -j DROP >/dev/null 2>&1
    iptables -D INPUT -p "$item" --dport "$port" -j ACCEPT >/dev/null 2>&1
    # insert new `ACCEPT` rule.
    iptables -I INPUT -p "$item" --dport "$port" -j ACCEPT
  done
}

main() {
  check_param $PROTOCOL $PORTS

  IFS=',' read -ra arr <<< "$PORTS"
  for port in "${arr[@]}"; do
    open_port "$port" $PROTOCOL || gen_result "failed" "open port failed: $port."
  done
}

main && gen_result "success"